package com.share.payment.service.impl;

import com.alibaba.fastjson2.JSON;
import com.share.common.core.domain.R;
import com.share.common.rabbit.constant.MqConst;
import com.share.common.rabbit.service.RabbitService;
import com.share.payment.service.OrderInfoApiClient;
import com.share.order.domain.OrderInfo;
import com.share.payment.domain.PaymentInfo;
import com.share.payment.domain.PaymentRecord;
import com.share.payment.service.IAliPayService;
import com.share.payment.service.IPaymentInfoService;
import com.share.payment.utils.AliPayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝支付Service实现类
 *
 * @author share
 * @date 2024-04-16
 */
@Slf4j
@Service
public class AliPayServiceImpl implements IAliPayService {

    @Autowired
    private IPaymentInfoService paymentInfoService;

    @Autowired
    private OrderInfoApiClient orderInfoApiClient;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private AliPayUtils aliPayUtils;

    /**
     * 创建支付
     *
     * @param orderNo 订单号
     * @param amount  金额
     * @param subject 商品名称
     * @return 支付二维码图片
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createPay(String orderNo, String amount, String subject) {
        try {
            log.info("开始创建支付，订单号：{}，金额：{}，商品名称：{}", orderNo, amount, subject);
            
            // 1. 查询订单信息
            OrderInfo orderInfo = orderInfoApiClient.getByOrderNo(orderNo).getData();
            if (orderInfo == null) {
                log.error("订单不存在，订单号：{}", orderNo);
                return null;
            }

            // 2. 查询并删除未支付的旧记录
            PaymentInfo oldPaymentInfo = paymentInfoService.getByOrderNo(orderNo);
            if (oldPaymentInfo != null && PaymentRecord.PAY_STATUS_UNPAID.equals(oldPaymentInfo.getPaymentStatus())) {
                paymentInfoService.removeById(oldPaymentInfo.getId());
                log.info("删除未支付的旧记录，订单号：{}", orderNo);
            }

            // 3. 创建新的支付记录
            PaymentInfo paymentInfo = new PaymentInfo();
            paymentInfo.setOrderNo(orderNo);
            paymentInfo.setUserId(orderInfo.getUserId());
            paymentInfo.setPayWay(PaymentRecord.PAY_WAY_ALIPAY);
            paymentInfo.setPaymentStatus(PaymentRecord.PAY_STATUS_UNPAID);
            paymentInfo.setAmount(new java.math.BigDecimal(amount));
            paymentInfo.setContent(subject);
            paymentInfo.setCreateTime(new Date());
            paymentInfo.setUpdateTime(new Date());
            paymentInfoService.save(paymentInfo);
            log.info("创建支付记录成功，订单号：{}", orderNo);

            // 4. 生成支付二维码
            String qrCode = aliPayUtils.generatePayQrCode(orderNo, amount, subject);
            log.info("生成支付二维码成功，订单号：{}", orderNo);
            
            return qrCode;
        } catch (Exception e) {
            log.error("创建支付失败，订单号：{}", orderNo, e);
            throw e;
        }
    }

    /**
     * 查询支付状态
     *
     * @param orderNo 订单号
     * @return 支付状态
     */
    @Override
    public String queryPayStatus(String orderNo) {
        try {
            log.info("开始查询支付状态，订单号：{}", orderNo);
            
            // 1. 查询支付记录
            PaymentInfo paymentInfo = paymentInfoService.getByOrderNo(orderNo);
            if (paymentInfo == null) {
                log.error("支付记录不存在，订单号：{}", orderNo);
                return "NOT_FOUND";
            }

            // 2. 如果已经支付成功，直接返回
            if (PaymentRecord.PAY_STATUS_PAID.equals(paymentInfo.getPaymentStatus())) {
                log.info("订单已支付成功，订单号：{}", orderNo);
                return "PAID";
            }

            // 3. 查询支付宝订单状态
            String status = aliPayUtils.queryPayStatus(orderNo);
            log.info("支付宝订单状态：{}，订单号：{}", status, orderNo);

            // 4. 更新支付记录状态
            if ("PAID".equals(status)) {
                paymentInfo.setPaymentStatus(PaymentRecord.PAY_STATUS_PAID);
                paymentInfo.setUpdateTime(new Date());
                paymentInfoService.updateById(paymentInfo);

                R<OrderInfo> byOrderNo = orderInfoApiClient.getByOrderNo(paymentInfo.getOrderNo());

                orderInfoApiClient.updateOrderInfo(byOrderNo.getData());
                
                // 发送支付成功消息
                rabbitService.sendMessage(MqConst.EXCHANGE_PAYMENT_PAY,
                        MqConst.ROUTING_PAYMENT_PAY,
                        paymentInfo.getOrderNo());
            }

            return status;
        } catch (Exception e) {
            log.error("查询支付状态失败，订单号：{}", orderNo, e);
            return "ERROR";
        }
    }

    /**
     * 处理支付回调
     *
     * @param params 回调参数
     * @return 处理结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean handlePayNotify(Map<String, String> params) {
        try {
            log.info("收到支付宝支付回调，参数：{}", params);
            
            // 1. 验证签名
            if (!aliPayUtils.verifyCallback(params)) {
                log.error("支付宝回调签名验证失败");
                return false;
            }

            // 2. 获取订单号
            String orderNo = params.get("out_trade_no");
            if (orderNo == null) {
                log.error("支付宝回调缺少订单号");
                return false;
            }

            // 3. 查询支付记录
            PaymentInfo paymentInfo = paymentInfoService.getByOrderNo(orderNo);
            if (paymentInfo == null) {
                log.error("支付记录不存在，订单号：{}", orderNo);
                return false;
            }

            // 4. 验证订单金额
            String totalAmount = params.get("total_amount");
            if (!paymentInfo.getAmount().toString().equals(totalAmount)) {
                log.error("订单金额不匹配，订单号：{}，系统金额：{}，支付宝金额：{}", 
                    orderNo, paymentInfo.getAmount(), totalAmount);
                return false;
            }

            // 5. 处理交易状态
            String tradeStatus = params.get("trade_status");
            log.info("支付宝回调交易状态：{}，订单号：{}", tradeStatus, orderNo);

            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 支付成功，更新支付状态
                paymentInfo.setPaymentStatus(PaymentRecord.PAY_STATUS_PAID);
                paymentInfo.setTransactionId(params.get("trade_no"));
                paymentInfo.setCallbackTime(new Date());
                paymentInfo.setCallbackContent(JSON.toJSONString(params));
                paymentInfo.setUpdateTime(new Date());
                paymentInfoService.updateById(paymentInfo);
                log.info("更新支付状态成功，订单号：{}", orderNo);

                R<OrderInfo> byOrderNo = orderInfoApiClient.getByOrderNo(paymentInfo.getOrderNo());

                orderInfoApiClient.updateOrderInfo(byOrderNo.getData());
                
                // 发送支付成功消息
                rabbitService.sendMessage(MqConst.EXCHANGE_PAYMENT_PAY,
                        MqConst.ROUTING_PAYMENT_PAY,
                        paymentInfo.getOrderNo());
                log.info("发送支付成功消息，订单号：{}", orderNo);
                
                return true;
            } else {
                log.error("支付宝回调交易状态异常，订单号：{}，交易状态：{}", orderNo, tradeStatus);
                return false;
            }
        } catch (Exception e) {
            log.error("处理支付宝回调失败", e);
            return false;
        }
    }
    
    /**
     * 生成支付二维码
     *
     * @param orderNo 订单号
     * @param amount  金额
     * @param subject 商品名称
     * @return 支付二维码URL
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String generatePayQrCode(String orderNo, String amount, String subject) {
        // 1. 查询订单信息
        OrderInfo orderInfo = orderInfoApiClient.getByOrderNo(orderNo).getData();
        if (orderInfo == null) {
            log.error("订单不存在，订单号：{}", orderNo);
            return null;
        }

        // 2. 创建支付记录
        PaymentInfo paymentInfo = new PaymentInfo();
        paymentInfo.setOrderNo(orderNo);
        paymentInfo.setUserId(orderInfo.getUserId());
        paymentInfo.setPayWay(PaymentRecord.PAY_WAY_ALIPAY);
        paymentInfo.setPaymentStatus(PaymentRecord.PAY_STATUS_UNPAID);
        paymentInfo.setAmount(new java.math.BigDecimal(amount));
        paymentInfo.setContent(subject);
        paymentInfo.setCreateTime(new Date());
        paymentInfoService.save(paymentInfo);

        // 3. 生成支付二维码
        return aliPayUtils.generatePayQrCode(orderNo, amount, subject);
    }
} 